package com.nercel.dsj.gksales.service.impl;

import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.nercel.dsj.gksales.constant.RedisKeyConstent;
import com.nercel.dsj.gksales.dao.mapper.SpikeMapper;
import com.nercel.dsj.gksales.exception.ResponseCode;
import com.nercel.dsj.gksales.exception.RestApiException;
import com.nercel.dsj.gksales.model.ListResult;
import com.nercel.dsj.gksales.model.QueryParams;
import com.nercel.dsj.gksales.model.entity.Spike;
import com.nercel.dsj.gksales.service.SpikeService;
import com.nercel.dsj.gksales.util.SignUtil;
import com.nercel.dsj.gksales.util.SpikeResult;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Transactional
public class SpikeServiceImpl implements SpikeService {

	@Autowired
	private SpikeMapper spikeMapper;

	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	@Autowired
	private RestTemplate restTemplate;

	@Value("${app.gkServiceApi}")
	private String gkServiceApi;

	static final String TEST_KEY = "1EF1236C2FCDE44AC00A37EDA2C4F7F7";

	@Override
	public void save(Spike t) {
		spikeMapper.insert(t);
		Integer limitNumber = t.getLimitNumber();
		// Redis里面用"limitNumber"+活动id作为key值，创建活动后将秒杀限制数存到Redis
		stringRedisTemplate.opsForValue().set(RedisKeyConstent.LIMITNUMBER + t.getId(),
				limitNumber == null ? "0" : limitNumber.toString());
	}

	@Override
	public void update(Spike t) {
		spikeMapper.updateByPrimaryKeySelective(t);
	}

	@Override
	public Spike findById(Integer id) {
		return spikeMapper.selectByPrimaryKey(id);
	}

	@Override
	public List<Spike> listAll() {
		return null;
	}

	@Override
	public void delete(Integer id) {
		spikeMapper.deleteByPrimaryKey(id);
	}

	@Override
	public ListResult<Spike> listWithPaging(QueryParams queryParams) {
		Page<Spike> page = PageHelper.startPage(queryParams.getPageNumber(), queryParams.getPageSize());
		spikeMapper.query(queryParams);
		return new ListResult<>(page);
	}

	@SuppressWarnings("unchecked")
	@Override
	public int spike(Spike spike, String phone) {
		Date now = new Date();
		// startTime>now活动开始时间还没到
		if (spike.getStartTime().compareTo(now) > 0) {
			return SpikeResult.FAILNOTSTARTED.getCode();
		}
		// endTime<now 活动已经结束
		if (spike.getEndTime().compareTo(now) < 0) {
			return SpikeResult.FAILENDED.getCode();
		}
		String limitNumber = stringRedisTemplate.opsForValue().get(RedisKeyConstent.LIMITNUMBER + spike.getId());
		// 防止Redis被清空，如果Redis被清空了，就从remainNumber中取值
		if (limitNumber == null) {
			limitNumber = spike.getRemainNumber().toString();
			stringRedisTemplate.opsForValue().set(RedisKeyConstent.LIMITNUMBER + spike.getId(),
					spike.getRemainNumber().toString());
		}
		int limitInt = Integer.parseInt(limitNumber);
		if (limitInt <= 0) {
			return SpikeResult.FAILSOLDOUT.getCode();
		}
		String url = gkServiceApi + "/api/v1/service/vip";
		String orderNumber = String.valueOf(Instant.now().toEpochMilli());
		Map<String, Object> requestMap = new HashMap<>();
		requestMap.put("userPhone", phone);
		requestMap.put("source", 5); // 来源 1激活码 2营销工具 3自行开通 4码上购
		requestMap.put("orderNumber", orderNumber);
		requestMap.put("createTime", Instant.now().getEpochSecond());
		requestMap.put("sendSms", true);
		requestMap.put("amount", 0);
		requestMap.put("value1", spike.getProviceCode());
		String sign = SignUtil.sign(requestMap, TEST_KEY);
		log.info("传入时的sign:{},传入时的Map:{},传入时的key:{}", sign, requestMap.toString(), TEST_KEY);
		requestMap.put("sign", sign);
		HttpHeaders headers = new HttpHeaders(); // http请求头
		headers.setContentType(MediaType.APPLICATION_JSON_UTF8); // 请求头设置属性
		HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<Map<String, Object>>(requestMap, headers);
		Map<String, Object> responseMap = restTemplate.postForObject(url, requestEntity, Map.class);
		// TODO 如果请求没有返回，会有问题
		if (responseMap != null && ResponseCode.SUCCESS.getCode().intValue() == (int) responseMap.get("code")) {
			Map<String, Object> data = (Map<String, Object>) responseMap.get("data");
			log.info("接口调用成功返回数据：{}-------------", data);
		} else {
			throw new RestApiException("接口调用失败！", ResponseCode.INTERNAL_SERVER_ERROR.getCode());
		}
		// 秒杀成功则剩余数量减1
		spike.setRemainNumber(spike.getRemainNumber() - 1);
		spikeMapper.updateByPrimaryKeySelective(spike); 
		// 存量减1
		stringRedisTemplate.opsForValue().set(RedisKeyConstent.LIMITNUMBER + spike.getId(),
				String.valueOf(limitInt - 1));
		return SpikeResult.SUCCESS.getCode();
	}

}
